Une intro…. Pas si petite

Pour suivre ce récapitulatif, veuillez installer les packages suivants:

  • Les packages du tidyverse: en tapant à la console install.packages("tidyverse").

  • Si vous ne les avez pas encore, les packages rmarkdown, knitr et devtools en tapant à la console install.packages(c("rmarkdown", "devtools")).


Pour ceux qui n’étaient pas là , vous avez raté quoi….

A la séance 3, on a eu une bonne dose d’installation qui a fait abandonné plusieurs personnes au cours de la séance parce que les amis n’avaient pas installé les packages nécessaires pour la séance. A la séance 4, on a essayé de rattraper le tir en montrant un peu le tidyverse, le ggplot2, les tests statistiques et une présentation sur la création de packages sous R. Malheureusement, on n’a pas pas pu faire les boucles et le if. On va y revenir dans le récapitulatif.

Outre la séance d’installation de la séance 3, on a introduit les projets de RStudio, le rmarkdown et on a effectué une petite introduction au tidyverse. On a ainsi appris à créer et gérer un projet sous Rstudio, traiter un document rmarkdown et on a lancé les bases du tidyverse avec un focus sur l’opérateur pipe… %>% Au passage on a appris quelques raccourcis claviers dont je vais reparler.

Quelques personnes s’étaient plaintes sur l’impossibilité de réaliser des documents lourds et structurés avec du rmarkdown. Je vais essayer de montrer que c’est faux et de vous faire prendre goût à rédiger vos documents et vos rapports dans la section sur rmarkdown, avec une introduction au bookdown. J’avais aussi promis de faire un clin d’œil sur le blogdown pour vous montrer rapidos comment créer votre propre blog ou site web, qui vous permettra si vous le nourrissez régulièrement de vous mettre à jour, d’apprendre aux autres et d’apprendre des autres aussi. J’ai aussi introduit une sous-section dessus dans la partie rmarkdown. Si c’est seulement cette section sur rmarkdown et compagnies qui vous intéresse, allez lire la section là.

Vous vous rappeler de notre base sur les essais randomisés? Après avoir introduit le tidyverse, on va essayer de vérifier que les classes d’age sont respectées en faisant une pyramide des âges (on l’a faite à la séance 4), et ensuite, on va passer à des tests statistiques pour vérifier quelques associations. Le tout sera accompagné de visualisations graphiques avec ggplot2. Si c’est juste la section sur ggplot2 et ses visualisations qui vous intéresse, je vous conseille de vous y plonger ici. Par contre, si vous ne vous intéressez qu’à la partie stats, n’hésitez pas à aller là.

A la fin de la séance, on a fait une petite demonstration sur la création de packages. Je vais revenir là dessus et vous montrer au passage les boucles et le if, avec quelques astuces. C’est la partie programmation et consorts… Si vous êtes là que pour ça, allez directement à la section concernée

Ça fait beaucoup de choses non? On y va! 1

Gestion d’un projet sous RStudio.

Structure du répertoire de travail

L’idee des projets est de mieux organiser votre travail - ou votre projet- sous R en gardant le repertoire de travail au repertoire du projet et en adopdant une hierarchie des dossiers qui va vous permettre de garder de bonnes habitudes de travail et de rigueur. La structure du dossier final de projet est la suivante 2:

      dossier_projet
        +
        ++++ dossier_projet.Rproj
        +
        ++++++++ data/
        +         +
        +         ++++++++++ cas_pratique.dta
        +         ++++++++++ cas_pratique.RData
        +         ++++++++++ cas_pratique.sav
        +         ++++++++++ cas_pratique.txt
        +         ++++++++++ cas_pratique.xlsx
        +         
        ++++++++ input/
        +
        ++++++++ output/
        +           +++++++ figures/
        +           +
        +           +++++++ data/
        +
        ++++++++ 1-premier-script.R
        +
        ++++++++ 2-un-document-markdown.Rmd
        +
        ++++++++ readme.txt
        

On commence par un dossier vide qui va etre le dossier de notre projet. Ce dossier sera de-facto le repertoire de travail lorsque l’on va lancer le projet sous Rstudio, ce qui permet d’eviter la partie set/get/wd.

Le dossier contient trois sous-dossiers 3:

  • Un dossier data dans lequel devraient se trouver les bases de donnees de notre analyse.

  • Un dossier input ou seront les figures et tout autre objets qui viendront enrichir notre travail, sans forcement provenir de R (captures d’ecran, etc.)

  • Un dossier output ou sera les sorties qui seront realisees avec R. Ces sorties sont divisees en deux principales parties: les figures et les graphes.

Creation du projet

On a d’abord creer notre projet en allant dans File > New Project.... On a obtenu la fenetre suivante et on a creer le projet dans un dossier. On a insiste sur le fait qu’un projet est en fait un dossier que Rstudio va creer. On a donc choisi l’option New Directory, puis l’option New Project et enfin un repertoire ou le dossier du projet va etre.

On a utilise les navigations dans l’onglet Files du quatrieme panneau (en bas a droite pour ceux qui n’on pas change la disposition par defaut) pour creer l’arborescence qu’on a presente en haut. On a alors introduit un fichier rmarkdown, qui devait contenir les codes et les output de nos travaux, et on l’a enregistre dans le dossier du projet. La prochaine section va en detail sur le rmarkdown et explique un peu comment il est concu.

Presentation et Gestion du rmarkdown

Historique

Comment est né R Markdown? 4 De l’idée de faire du texte et du code R en même temps dans un même fichier, de façon reproductible et facilement partageable. Le pionnier de cette idée est Yihui Xie, qui s’est appuyé sur l’ancêtre du travail reproductible Sweave, qui permettait de faire du LaTeX et du R dans un même fichier, afin de faciliter la rédaction de rapports qui nécessitaient les mêmes types d’analyses. Il a lancé le package knitr sur lequel repose le package rmarkdown. C’est l’essentiel. R Markdown est souvent présenté sous la forme suivante, mettant en exergue les formats de sortie.

Pour ceux qui sont presses sur la syntaxe du markdown ou carrement n’ont pas envie de se taper la lecture de tout le tuto, je vous conseille de lire la feuille de triche faite par Rstudio. Vous pouvez ainsi sauter toute cette section pour aller lire celle sur le tidyverse et les tests statistiques.

Pourquoi utiliser R Markdown ?

“What is Reproducibility? Reproducibility is one of the main principles of the scientific method, and refers to the ability of a test or experiment to be accurately reproduced, or replicated, by someone else working independently.”

Yihui Xie

A cause des raisons suivantes:

  1. La reproductibilite. L’idee de la reproductibilite est de permettre a tout un chacun de pouvoir reprendre sa propre etude et ses propres analyses, en suivant exactement les memes etapes que soit.

  2. R Markdown a une syntaxe facile à maîtriser; en quelques minutes d’effort on acquiert l’essentiel pour écrire son document.

  3. Avec un seul fichier, vous pouvez avoir plusieurs formats à la clé (Word, PDF (à condition d’avoir LaTeX), HTML)

  4. Cela permet de faciliter le partage de fichiers, l’explication des scripts effectués et le partage au niveau de la communauté scientifique.

Et enfin, on peut écrire tout un article en Markdown. Faites un tour sur la Gallerie de rmarkdown et regardez la variété de documents que l’on peut réaliser avec.

Creation d’un fichier rmarkdown

On a appris a creer un fichier rmarkdown sous Rstudio. Pour ce faire, lancez R Markdown en effectuant les taches suivantes dans R Studio:

File>New File>R Markdown

Il apparaît alors une fenêtre demandant de préciser les paramètres du fichier que l’on a créé. Il faut preciser le titre du document, son auteur et le format de sortie. Il est possible d’avoir du word (en fait un .docx) ou du pdf comme format de sortie, je reviendrai dans la section sur la sortie pdf. Pour la version word, je vous renvoie a la documentation5.

Une fois les paramètres spécifiés, on peut passer à l’analyse du document basique qui sert de début à l’apprentissage du langage de R Markdown. Il s’agit du document suivant:

L’en-tête d’un document R Markdown

L’en-tête d’un document R Markdown est constitué de petites phrases entourées d’un ---, comme dans le document utilisé pour créer ce fichier que vous lisez:

---
title: "Récapitulatif de la séance trois"
author: "Yves Amevoin, ISE"
date: "Novembre 2018"
output:
  html_document:
    css: style.css
    highlight: kate
    theme: yeti
    toc: yes
    toc_float: TRUE
    dpi: 600
    dev: "png"
    code_download: TRUE
---

Cet ensemble de phrases contient les informations nécessaires au paramétrage du document. Le document lui même peut être considéré comme un ensemble de données (section, texte, code R), et les parties situées entre ces ---, des informations donnant des attributs et des paramètres à ces données (couleur, titre, date de création, format): On parle de métadonnées. Ces attributs doivent être transmis à un langage qui se charge de les stocker et de les rendre au document pour en changer l’aspect ou ajouter des informations. Ce langage, c’est le YAML qui signifiait au début Yet Another Markup Language mais qui est devenu YAML Aint Markup Language. En clair le YAML c’est quoi? Une syntaxe qui permet de stocker des données sur le document et qui les utilise pour paramétrer le document R Markdown et y ajouter des choses. Cette syntaxe est très stricte, avec des deux points, des retours à la ligne, des guillemets et des indentations (petits espaces après le retour à la ligne) pour cibler les sous-options d’une option mere. Par exemple, pour le html_document qui signifie le format de sortie, on a demande d’inclure une table des matieres (toc:yes), la possibilite de telecharger les codes du document (code_download : TRUE). Les options sont en general liees aux format de sortie liees au document que vous voulez obtenir. Comment les données sur le document sont stockées? Dans un objet appelé metadata dans le package rmarkdown. Regardez:

## [1] "Récapitulatif des séances trois et quatre"

Pour un document HTML, il existe une pléthore de paramètres (auteur, date, fonte, etc.) et l’on peut même ajouter un ficher qui prend bien en charge la mise en forme, comme mon fichier style.css que vous voyez dans l’option css. On peut en faire de même avec un fichier PDF. On pourrait écrire un article dessus. Mais en général le petit nombre de paramètres par défaut proposé par Rstudio suffit amplement pour des documents de petite envergure. Dans le cas où vous voulez des documents lourds, il serait souhaitable de jeter un coup d’œil sur les pages suivantes afin de regarder comment contrôler la mise en page:

Les chunks

Un fichier rmarkdown est un fichier dans lequel se trouvent les codes qui vont permettre de generer les analyses et les resultats associes aux analyses proprement dites ainsi que les commentaires de ces analyses. Ces codes se trouvent dans des portions grises appelees chunk, afin de les distinguer des commentaires - du texte brut - que vous ecrivez. Comment inserer un chunk lorsque l’on travaille sous Rstudio? Pour inserer un chunk R sous Rstudio, utilisez le raccourci clavier CTRL+ALT+I. Mais si vous voulez vous taper la syntaxe de l’ecriture, un chunk commence par ces trois accents graves ``` suivis de r que l’on met entre des accolades, ```{r} et il se termine par trois accents graves aussi ```. Une erreur commune est de ne pas terminer son chunk ou d’effacer par maladresse les trois accents de la fin.

Les chunk peuvent avoir des options en fonction de comment l’on veut traiter le rendu. En general on peut soit vouloir afficher le code ou pas, soit la sortie du code ou pas, soit evaluer le code ou pas. Vous pouvez parcourir les options d’un chunk R que vous aurez insere en cliquant sur les parametres du chunk.

Une fois que vous verrez comment les options ont ete inserees, vous pouvez taper le code vous meme. On a donc recharge notre base de donnees en utilisant le chunk suivant:

Les chunks par defaut, supposent que vous avez du R comme langage, mais il est possible de creer des chuncks avec d’autres langages. Vous pouvez choisir le langage associe au chunk que vous voulez inserer en cliquant sur insert en haut a gauche de l’editeur. En bas par exemple, j’insere un chunk avec des commandes systemes.

## fom_my_key
## Mega
## personal_folder
## personal_learnings
## personal_projects
## ressources
## software
## test_projets
## work_for_others

Si vous faites de meme, vous verrez que votre chunk commence par ```{bash}. Cela permet a knitr de savoir quel langage utilise dans le chunk.

Les chunk peuvent avoir un nom. L’idee est de leur permettre d’etre facilement accessible en utilisant les onglets de navigation de Rstudio. Pour nommer un chunk, il suffit de mettre

Le chunk setup

Des listes et des formules

On peut faire des listes avec un fichier R Markdown de façon très facile:

Une liste numérotée:

1. Un
2. Deux
3. Trois
3. Quatre

Vous remarquerez qu'il augmente en même temps le chiffre non?

Et des listes non numérotées comme avec des tirets:

- Un
- Deux
- Trois

Ou avec des points:

* Un
* Deux
* Trois

Ou les deux:

* J'aime la biostatistique
    + Les eleves n'ont pas installer les packages
    + Coucou a tous.
  
* Il sait mettre la différence entre les rondes blanches et les noires. Il suffit d'aller à la ligne et de mettre deux indentations avec le `backspace` (l'accent grave est pour mettre en exergue) pour avoir des sous-listes.

Le texte précédent donne la sortie suivante:

Une liste numérotée:

  1. Un
  2. Deux
  3. Trois
  4. Quatre

Vous remarquerez qu’il augmente en même temps le chiffre non?

Et des listes non numérotées comme avec des tirets:

  • Un
  • Deux
  • Trois

Ou avec des points:

  • Un
  • Deux
  • Trois

Ou les deux:

  • J’aime la biostatistique
    • Les eleves n’ont pas installer les packages
    • Coucou a tous.
  • Il sait mettre la différence entre les rondes blanches et les noires. Il suffit d’aller à la ligne et de mettre deux indentations avec le backspace pour avoir des sous-listes.

On peut faire du pdf base sur du \(\LaTeX\) dans rmarkdown, comme je l’avais dit en montrant cette image ici. On peut insérer des formules \(\LaTeX\) dans un document R Markdown peu importe le format de sortie, en utilisant la même syntaxe que celle de LaTeX:

$\sum_{i=1}^n\alpha_i$;

$tan(x)=\frac{cos(x)}{sin(x)}$

\(\sum_{i=1}^n\alpha_i\);

\(tan(x)=\frac{cos(x)}{sin(x)}\)

Insérer des Images, Insérer des tableaux

Le fichier que vous lisez est plein d’images qui permettent d’illustrer les propos. On peut insérer des images dans un fichier R Markdown. Pour cela il faut donner un identifiant à l’image (comme par exemple monimage) et l’insérer dans le document de la façon suivante:

![Le titre de l'image][monimage]

Mais comment R Markdown retrouve l’image correspondante? En mettant à la fin du fichier les références permettant d’atteindre l’image. La syntaxe est la suivante pour un format png par exemple.

[monimage]: Chemin_vers_limage/image.png "Texte popup qui s'affiche quand la souris survole"

L’identifiant peut être utilisé pour indexer l’image à travers un lien dans le document, comme j’ai fait pour ici

Les Tableaux

Il existe plusieurs manières d’insérer un tableau, la façon la plus recommandée étant d’utiliser le package knitr comme présenté précédemment. Cependant, il est possible d’insérer un tableau dans un document R Markdown de la façon suivante, ou les deux points permettent de dire comment l’on veut aligner les elements du tableau.

: Un Tableau

|Aligné à Droite|Aligné à Gauche|Par Défaut|Au Centre|
|--------------:|:--------------|----------|:-------:|
|Installez      |N'oubliez pas  |Package    | les     |
|les            |Dinstaller     |Installez  |package    |
|package        |les            |avant de venir|5      |


Un Tableau
Aligné à Droite Aligné à Gauche Par Défaut Au Centre
Installez N’oubliez pas Package les
les Dinstaller Installez package
package les avant de venir 5

Les petits plus pour finir

Un fichier comme celui-ci … On fait comment?

Pour créer un fichier comme celui-ci, rien de plus simple! Créez un document R Markdown normal et ajoutez quelques paramètres pour le rendre plus attractif. J’ai d’abord changé le thème général en choisissant le thème flatly que j’aime bien. Pour cela, il faut ajouter la syntaxe theme: flatly dans le bloc YAML. J’ai aussi ajouter la table des matières, ainsi qu’un défilement plutôt intéressant de la table:

---
# Le haut de la syntaxe
toc: true
toc_float:
      collapse: true
      smooth_scroll: true
---

La mise en forme de la page et le style ont été gérés avec un fichier de configuration, appelé style.css. A quoi sert un fichier .css? A définir la mise en page de pages web. J’ai juste utilisé quelques bribes de connaissance dans le domaine pour gérer la mise en page. Le css peut à lui tout seul faire l’objet d’un autre fichier tutoriel. Mais pas besoin de grand choses pour une mise en forme comme celle utilisée dans ce document. Il suffit juste de jeter un coup d’oeil sur mon fichier pour vous en rendre compte. Dans le fichier css,body représente le corps du document et les propriétés définissent comment le document est formaté. Ainsi, mon document est mis en fonte Georgia, 13pt, et justifié avec la syntaxe suivante:

body{
  font-family: Georgia;
  font-size: 13pt;
  text-align: justify;
}

h1, h2, h3 désignent les sections et sous sections de niveaux 1,2,3 respectivement. J’ai géré aussi la mise en forme de certains blocs dans le fichier css. Cela fera l’objet de la section suivante. Pour plus d’informations sur le css, rendez-vous6 sur la page . Reste à inclure le fichier dans le document à travers la syntaxe YAML css: style.css après l’avoir mis dans le même répertoire que le fichier R Markdown.

La mise en forme des blocs

La mise en forme des blocs s’est faite en utilisant aussi du css. Le package knitr permet d’insérer d’autres langages que du R dans les blocs de code et même de les exécuter à travers un système nommé engine. Il est aussi possible de créer des blocs vides, non conformes à un langage précis ou des blocs propres formatés en Markdown. C’est ce qui a été fait dans les blocs en marron dans le document. Pour créer un bloc propre en Markdown, dans le fichier R Markdown on écrit un bloc suivant:

<div class="untype">
<p>n = 10 rnorm(n)</p>
</div>

Il faut ensuite faire la mise en forme en y dans joignant le fichier .css la forme dédiée au bloc untype. Dans le fichier .css, on pourra donc écrire les blocs de code suivants:

.untype{
  background-color: #f9f5f3;
  font-size:12pt;
  font-family: "Georgia", serif;
  padding-top:5px;
  padding-left:8px;
  border-left: 5px solid #e8dad1;
  padding-bottom:5px;
  padding-right:5px;
}

Ainsi, à chaque fois que l’on choisira un bloc de type untype, il aura les propriétés cités plus haut.

Et pour un document lourd? Ou un article?

N’exagérons rien, me direz-vous…. Pourquoi rédiger un livre entier ou un article dans Rstudio alors qu’on a Word?

Parce que c’est reproductible

Vous vous rendez-compte d’une erreur? Une modification et ça y est! tout est réglé. Pas de copier coller avec des pertes de temps et des risques d’erreurs. Aussi, vous pouvez juste balancer le code à un ami et il peut reprendre les mêmes analyses et observer si vous avez tout bien fait, ou loupez quelque chose… Ça n’arrange que la recherche.

Revenons au titre, comment rédiger un article sous R Markdown. Lorsque vous décidez de créer un nouveau document sous R Markdown, vous avez une page suivante correspondant au document que vous voulez:

[][Template]

En bas, vous pouvez choisir l’option From Template pour créer le document à partir d’exemplaires existant déjà. Cette section nous permet de choisir un ensemble d’exemplaires et de les utiliser à outrance lorsque vous souhaitez faire un nouveau document R Markdown, en passant outre le format basique que Rstudio propose.

Qu’est ce qu’un Template de R markdown?

C’est un ensemble de formats et de propriétés prédéfinis qui vous permettent d’accélérer le travail si vous avez l’habitude d’écrire des documents qui ont la même structure. On peut en créer un avec R Markdown, mais cela nécessite un peu de tweak…

Vous pouvez néanmoins utiliser des Template existants, en installant le package rticles par exemple qui vous permettra d’avoir les formats prédéfinis pour les articles dans différents journaux. Si vous pensez publier dans tel ou tel journal, vous pouvez définir un Template pour ce journal s’il n’existe pas et rédiger avec, ou même le partager. Installez le package rticles,

Puis vous verrez les exemplaires pour les articles dans la section From Template. Pour le reste, à vous de jouer. Vous pouvez ajouter d’autres Templates en faisant un tour sur la gallerie de R Markdown.

Le bookdown

Peut-on ecrire un livre avec du rmarkdown? Oui, c’est possible. Et pour rendre le tout beau, avec du bookdown. Jetez-vous pour regarder. Si vous voulez juste acquerir les bases necessaires pour rediger, on continue.

Le blogdown

Le tidyverse

Les figures avec ggplot2

Les tests statistiques

La creation de package sous Rstudio

Les petits plus pour finir…

Je ne saurais terminer sans donner une documentation pour ceux et celles qui veulent approfondir leur connaissance en stats et R.


  1. Je vous présente des excuses si il y a quelques accents qui manquent dans mon texte, dû à l’utilisation abusive d’un clavier anglais.

  2. Le readme.txt que j’ai ajoute n’est pas obligatoire, mais il serait interessant d’expliquer aux gens le dossier et ce qu’il y a l’interieur, ou meme ton futur toi qui ne comprendrait plus rien dans quelques annees au travail que tu avais fait. Certains en font un readme.html (ecrit en markdown), d’autres un readme.txt.

  3. Libre a vous d’organiser votre dossier de travail comme vous voulez, pourvue que vous gardiez une certaine rigueur dans l’organisation. Je presente ici mon workflow habituel (Pas vraiment puisque dans mon workflow habituel, le dossier data se trouve dans input)

  4. Cette section provient d’un document explicatif sur le Markdown que j’avais ecris prealablement. Les personnes qui trouveraient une quelconque similitude avec un de mes anciens docs… No comments.

  5. C’est vraiment hyper simple de modifier le format de sortie word

  6. Je me suis rendu compte qu’il est long quand je l’ai fini.

LS0tCnRpdGxlOiAiUsOpY2FwaXR1bGF0aWYgZGVzIHPDqWFuY2VzIHRyb2lzIGV0IHF1YXRyZSIKYXV0aG9yOiAiWXZlcyBBbWV2b2luLCBJU0UiCmRhdGU6ICJEw6ljZW1icmUgMjAxOCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjc3M6IHN0eWxlLmNzcwogICAgaGlnaGxpZ2h0OiBrYXRlCiAgICB0aGVtZTogeWV0aQogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogVFJVRQogICAgZHBpOiAxODAwCiAgICBkZXY6ICJwbmciCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCi0tLQoKIyMgVW5lIGludHJvLi4uLiBQYXMgc2kgcGV0aXRlCgpQb3VyIHN1aXZyZSBjZSByw6ljYXBpdHVsYXRpZiwgdmV1aWxsZXogaW5zdGFsbGVyIGxlcyBwYWNrYWdlcyBzdWl2YW50czoKCi0gTGVzIHBhY2thZ2VzIGR1IGB0aWR5dmVyc2VgOiBlbiB0YXBhbnQgw6AgbGEgY29uc29sZSAKYGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpYC4KCi0gU2kgdm91cyBuZSBsZXMgYXZleiBwYXMgZW5jb3JlLCBsZXMgcGFja2FnZXMgYHJtYXJrZG93bmAsIGBrbml0cmAgZXQgYGRldnRvb2xzYCBlbiB0YXBhbnQgw6AgbGEgCmNvbnNvbGUgYGluc3RhbGwucGFja2FnZXMoYygicm1hcmtkb3duIiwgImRldnRvb2xzIikpYC4KCi0tLQoKYGBge2Jsb2NrIGludHJvLCB0eXBlID0gIm1vbnR5cGUyIn0KCiMjIyMgUG91ciBjZXV4IHF1aSBu4oCZw6l0YWllbnQgcGFzIGzDoCAsIHZvdXMgYXZleiByYXTDqSBxdW9pLi4uLgoKQSBsYSBzw6lhbmNlIDMsIG9uIGEgZXUgdW5lIGJvbm5lIGRvc2UgZCdpbnN0YWxsYXRpb24gcXVpIGEgZmFpdCBhYmFuZG9ubsOpIApwbHVzaWV1cnMgcGVyc29ubmVzIGF1IGNvdXJzIGRlIGxhIHPDqWFuY2UgcGFyY2UgcXVlIGxlcyBhbWlzIG4nYXZhaWVudCBwYXMgCmluc3RhbGzDqSBsZXMgcGFja2FnZXMgbsOpY2Vzc2FpcmVzIHBvdXIgbGEgc8OpYW5jZS4gQSBsYSBzw6lhbmNlIDQsIG9uIGEgZXNzYXnDqQpkZSByYXR0cmFwZXIgbGUgdGlyIGVuIG1vbnRyYW50IHVuIHBldSBsZSBgdGlkeXZlcnNlYCwgbGUgZ2dwbG90MiwgbGVzIHRlc3RzCnN0YXRpc3RpcXVlcyBldCB1bmUgcHLDqXNlbnRhdGlvbiBzdXIgIGxhIGNyw6lhdGlvbiBkZSBwYWNrYWdlcyBzb3VzIFIuIApNYWxoZXVyZXVzZW1lbnQsIG9uIG4nYSBwYXMgcGFzIHB1IGZhaXJlIGxlcyBib3VjbGVzIGV0IGxlIGlmLiAKT24gdmEgeSByZXZlbmlyIGRhbnMgbGUgcsOpY2FwaXR1bGF0aWYuCgpPdXRyZSBsYSBzw6lhbmNlIGQnaW5zdGFsbGF0aW9uIGRlIGxhIHPDqWFuY2UgMywgb24gYSBpbnRyb2R1aXQgbGVzIHByb2pldHMgZGUgCipSU3R1ZGlvKiwgbGUgYHJtYXJrZG93bmAgZXQgb24gYSBlZmZlY3R1w6kgdW5lIHBldGl0ZSBpbnRyb2R1Y3Rpb24gYXUgYHRpZHl2ZXJzZWAuIApPbiBhIGFpbnNpIGFwcHJpcyDDoCBjcsOpZXIgZXQgZ8OpcmVyIHVuIHByb2pldCBzb3VzICpSc3R1ZGlvKiwgdHJhaXRlciB1biBkb2N1bWVudApgcm1hcmtkb3duYCBldCBvbiBhIGxhbmPDqSBsZXMgYmFzZXMgZHUgYHRpZHl2ZXJzZWAgYXZlYyB1biBmb2N1cyBzdXIgbOKAmW9ww6lyYXRldXIKcGlwZS4uLiAlPiUgQXUgcGFzc2FnZSBvbiBhIGFwcHJpcyBxdWVscXVlcyByYWNjb3VyY2lzIGNsYXZpZXJzIApkb250IGplIHZhaXMgcmVwYXJsZXIuIAoKUXVlbHF1ZXMgcGVyc29ubmVzIHMnw6l0YWllbnQgcGxhaW50ZXMgc3VyIGwnaW1wb3NzaWJpbGl0w6kgZGUgcsOpYWxpc2VyIGRlcyAKZG9jdW1lbnRzIGxvdXJkcyBldCBzdHJ1Y3R1csOpcyBhdmVjIGR1IGBybWFya2Rvd25gLiBKZSB2YWlzIGVzc2F5ZXIgZGUgbW9udHJlciAKcXVlIGMnZXN0IGZhdXggZXQgZGUgdm91cyBmYWlyZSBwcmVuZHJlIGdvw7t0IMOgIHLDqWRpZ2VyIHZvcyBkb2N1bWVudHMgZXQgdm9zIApyYXBwb3J0cyBkYW5zIGxhIHNlY3Rpb24gc3VyIGBybWFya2Rvd25gLCBhdmVjIHVuZSBpbnRyb2R1Y3Rpb24gYXUgYGJvb2tkb3duYC4gCkonYXZhaXMgYXVzc2kgcHJvbWlzIGRlIGZhaXJlIHVuIGNsaW4gZOKAmcWTaWwgc3VyIGxlIGBibG9nZG93bmAgcG91ciB2b3VzIG1vbnRyZXIgCnJhcGlkb3MgY29tbWVudCBjcsOpZXIgdm90cmUgcHJvcHJlIGJsb2cgb3Ugc2l0ZSB3ZWIsIHF1aSB2b3VzIHBlcm1ldHRyYSBzaSB2b3VzIGxlCm5vdXJyaXNzZXogcsOpZ3VsacOocmVtZW50IGRlIHZvdXMgbWV0dHJlIMOgIGpvdXIsIGQnYXBwcmVuZHJlIGF1eCBhdXRyZXMgZXQgCmQnYXBwcmVuZHJlIGRlcyBhdXRyZXMgYXVzc2kuIEonYWkgYXVzc2kgaW50cm9kdWl0IHVuZSBzb3VzLXNlY3Rpb24gZGVzc3VzIApkYW5zIGxhIHBhcnRpZSBgcm1hcmtkb3duYC4gU2kgYydlc3Qgc2V1bGVtZW50IGNldHRlIHNlY3Rpb24gc3VyIGBybWFya2Rvd25gIGV0CmNvbXBhZ25pZXMgcXVpIHZvdXMgaW50w6lyZXNzZSwgYWxsZXogbGlyZSBsYSBbc2VjdGlvbiBsw6BdKCNsaWVudmVyc2xhc2VjdGlvbnJtZCkuCgpWb3VzIHZvdXMgcmFwcGVsZXIgZGUgbm90cmUgYmFzZSBzdXIgbGVzIGVzc2FpcyByYW5kb21pc8Opcz8gQXByw6hzIGF2b2lyIAppbnRyb2R1aXQgbGUgYHRpZHl2ZXJzZWAsIG9uIHZhIGVzc2F5ZXIgZGUgdsOpcmlmaWVyIHF1ZSBsZXMgY2xhc3NlcyBkJ2FnZSBzb250IApyZXNwZWN0w6llcyBlbiBmYWlzYW50IHVuZSBweXJhbWlkZSBkZXMgw6JnZXMgKG9uIGwnYSBmYWl0ZSDDoCBsYSBzw6lhbmNlIDQpLApldCBlbnN1aXRlLCBvbiB2YSBwYXNzZXIgw6AgZGVzIHRlc3RzIHN0YXRpc3RpcXVlcyBwb3VyIHbDqXJpZmllciBxdWVscXVlcyAKYXNzb2NpYXRpb25zLiBMZSB0b3V0IHNlcmEgYWNjb21wYWduw6kgZGUgdmlzdWFsaXNhdGlvbnMgZ3JhcGhpcXVlcyBhdmVjIGBnZ3Bsb3QyYC4KU2kgYydlc3QganVzdGUgbGEgc2VjdGlvbiBzdXIgYGdncGxvdDJgIGV0IHNlcyB2aXN1YWxpc2F0aW9ucyBxdWkgdm91cyBpbnTDqXJlc3NlLCAKamUgdm91cyBjb25zZWlsbGUgZGUgdm91cyB5IFtwbG9uZ2VyIGljaV0oI2xpZW52ZXJzbGFzZWN0aW9uZ2dwbG90MikuIFBhciBjb250cmUsIApzaSB2b3VzIG5lIHZvdXMgaW50w6lyZXNzZXogcXUnw6AgbGEgcGFydGllIHN0YXRzLCAKW24naMOpc2l0ZXogcGFzIMOgIGFsbGVyIGzDoF0oI2xpZW52ZXJzbGVzc3RhdHMpLgoKQSBsYSBmaW4gZGUgbGEgc8OpYW5jZSwgb24gYSBmYWl0IHVuZSBwZXRpdGUgZGVtb25zdHJhdGlvbiBzdXIgbGEgY3LDqWF0aW9uIGRlIHBhY2thZ2VzLiAKSmUgdmFpcyByZXZlbmlyIGzDoCBkZXNzdXMgZXQgdm91cyBtb250cmVyIGF1IHBhc3NhZ2UgbGVzIGJvdWNsZXMgZXQgbGUgaWYsIGF2ZWMgCnF1ZWxxdWVzIGFzdHVjZXMuIEMnZXN0IGxhIHBhcnRpZSBwcm9ncmFtbWF0aW9uIGV0IGNvbnNvcnRzLi4uIFNpIHZvdXMgw6p0ZXMgbMOgIHF1ZSBwb3VyIMOnYSwKYWxsZXogZGlyZWN0ZW1lbnQgw6AgW2xhIHNlY3Rpb24gY29uY2VybsOpZV0oI2xpZW52ZXJzbGFzZWN0aW9ucGFja2FnZSkKCsOHYSBmYWl0IGJlYXVjb3VwIGRlIGNob3NlcyBub24/IE9uIHkgdmEhIFteN10KYGBgCgoKIyMgR2VzdGlvbiBkJ3VuIHByb2pldCBzb3VzICpSU3R1ZGlvKi4KCiMjIyBTdHJ1Y3R1cmUgZHUgcsOpcGVydG9pcmUgZGUgdHJhdmFpbAoKTCdpZGVlIGRlcyBwcm9qZXRzIGVzdCBkZSBtaWV1eCBvcmdhbmlzZXIgdm90cmUgdHJhdmFpbCAtIG91IHZvdHJlIHByb2pldC0gc291cyBSIGVuIGdhcmRhbnQgbGUgcmVwZXJ0b2lyZQpkZSB0cmF2YWlsIGF1IHJlcGVydG9pcmUgZHUgcHJvamV0IGV0IGVuIGFkb3BkYW50IHVuZSBoaWVyYXJjaGllIGRlcyBkb3NzaWVycyBxdWkgdmEgdm91cyBwZXJtZXR0cmUgZGUgZ2FyZGVyCmRlIGJvbm5lcyBoYWJpdHVkZXMgZGUgdHJhdmFpbCBldCBkZSByaWd1ZXVyLiBMYSBzdHJ1Y3R1cmUgZHUgZG9zc2llciBmaW5hbCBkZSBwcm9qZXQgZXN0IGxhIHN1aXZhbnRlIFteMV06CgogICAgICAgICAgZG9zc2llcl9wcm9qZXQKICAgICAgICAgICAgKwogICAgICAgICAgICArKysrIGRvc3NpZXJfcHJvamV0LlJwcm9qCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgZGF0YS8KICAgICAgICAgICAgKyAgICAgICAgICsKICAgICAgICAgICAgKyAgICAgICAgICsrKysrKysrKysgY2FzX3ByYXRpcXVlLmR0YQogICAgICAgICAgICArICAgICAgICAgKysrKysrKysrKyBjYXNfcHJhdGlxdWUuUkRhdGEKICAgICAgICAgICAgKyAgICAgICAgICsrKysrKysrKysgY2FzX3ByYXRpcXVlLnNhdgogICAgICAgICAgICArICAgICAgICAgKysrKysrKysrKyBjYXNfcHJhdGlxdWUudHh0CiAgICAgICAgICAgICsgICAgICAgICArKysrKysrKysrIGNhc19wcmF0aXF1ZS54bHN4CiAgICAgICAgICAgICsgICAgICAgICAKICAgICAgICAgICAgKysrKysrKysgaW5wdXQvCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgb3V0cHV0LwogICAgICAgICAgICArICAgICAgICAgICArKysrKysrIGZpZ3VyZXMvCiAgICAgICAgICAgICsgICAgICAgICAgICsKICAgICAgICAgICAgKyAgICAgICAgICAgKysrKysrKyBkYXRhLwogICAgICAgICAgICArCiAgICAgICAgICAgICsrKysrKysrIDEtcHJlbWllci1zY3JpcHQuUgogICAgICAgICAgICArCiAgICAgICAgICAgICsrKysrKysrIDItdW4tZG9jdW1lbnQtbWFya2Rvd24uUm1kCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgcmVhZG1lLnR4dAogICAgICAgICAgICAKCk9uIGNvbW1lbmNlIHBhciB1biBkb3NzaWVyIHZpZGUgcXVpIHZhIGV0cmUgbGUgZG9zc2llciBkZSBub3RyZSBwcm9qZXQuIENlIGRvc3NpZXIgc2VyYSBkZS1mYWN0byBsZQpyZXBlcnRvaXJlIGRlIHRyYXZhaWwgbG9yc3F1ZSBsJ29uIHZhIGxhbmNlciBsZSBwcm9qZXQgc291cyAqUnN0dWRpbyosIGNlIHF1aSBwZXJtZXQgZCdldml0ZXIKbGEgcGFydGllIGBzZXQvZ2V0L3dkYC4KCkxlIGRvc3NpZXIgY29udGllbnQgdHJvaXMgc291cy1kb3NzaWVycyBbXjJdOgoKLSBVbiBkb3NzaWVyIGBkYXRhYCBkYW5zIGxlcXVlbCBkZXZyYWllbnQgc2UgdHJvdXZlciBsZXMgYmFzZXMgZGUgZG9ubmVlcyBkZSBub3RyZSBhbmFseXNlLgoKLSBVbiBkb3NzaWVyIGBpbnB1dGAgb3Ugc2Vyb250IGxlcyBmaWd1cmVzIGV0IHRvdXQgYXV0cmUgb2JqZXRzIHF1aSB2aWVuZHJvbnQgZW5yaWNoaXIgbm90cmUgdHJhdmFpbCwKc2FucyBmb3JjZW1lbnQgcHJvdmVuaXIgZGUgUiAoY2FwdHVyZXMgZCdlY3JhbiwgZXRjLikKCi0gVW4gZG9zc2llciBgb3V0cHV0YCBvdSBzZXJhIGxlcyBzb3J0aWVzIHF1aSBzZXJvbnQgcmVhbGlzZWVzIGF2ZWMgYFJgLiBDZXMgc29ydGllcyBzb250IGRpdmlzZWVzCmVuIGRldXggcHJpbmNpcGFsZXMgcGFydGllczogbGVzIGZpZ3VyZXMgZXQgbGVzIGdyYXBoZXMuCgojIyMgQ3JlYXRpb24gZHUgcHJvamV0CgpPbiBhIGQnYWJvcmQgY3JlZXIgbm90cmUgcHJvamV0IGVuIGFsbGFudCBkYW5zIGBGaWxlID4gIE5ldyBQcm9qZWN0Li4uYC4gT24gYSBvYnRlbnUgbGEgZmVuZXRyZSBzdWl2YW50ZSBldCBvbiBhIGNyZWVyIGxlIHByb2pldCBkYW5zIHVuIGRvc3NpZXIuIE9uIGEgaW5zaXN0ZSBzdXIgbGUgZmFpdCBxdSd1biBwcm9qZXQKZXN0IGVuIGZhaXQgdW4gZG9zc2llciBxdWUgKlJzdHVkaW8qIHZhIGNyZWVyLgpPbiBhIGRvbmMgY2hvaXNpIGwnb3B0aW9uIGBOZXcgRGlyZWN0b3J5YCwgcHVpcyBsJ29wdGlvbiBgTmV3IFByb2plY3RgIGV0IGVuZmluIHVuIHJlcGVydG9pcmUKb3UgbGUgZG9zc2llciBkdSBwcm9qZXQgdmEgZXRyZS4KCmBgYHtyIGZpZ3VyZS1wcm9qZXQsIGVjaG89RkFMU0UsIG91dC53aWR0aCA9ICc0MDAlJ30Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImZpZ3VyZXMvcHJvamVjdF9jcmVhdGlvbi5wbmciKQoKYGBgCgoKCk9uIGEgdXRpbGlzZSBsZXMgbmF2aWdhdGlvbnMgZGFucyBsJ29uZ2xldCBgRmlsZXNgIGR1IHF1YXRyaWVtZSBwYW5uZWF1IChlbiBiYXMgYSBkcm9pdGUgcG91ciBjZXV4IHF1aSBuJ29uIHBhcyBjaGFuZ2UgbGEgZGlzcG9zaXRpb24gcGFyIGRlZmF1dCkgcG91ciBjcmVlciBsJ2FyYm9yZXNjZW5jZSBxdSdvbiBhIHByZXNlbnRlIGVuIGhhdXQuCk9uIGEgYWxvcnMgaW50cm9kdWl0IHVuIGZpY2hpZXIgcm1hcmtkb3duLCBxdWkgZGV2YWl0IGNvbnRlbmlyIGxlcyBjb2RlcyBldCBsZXMgb3V0cHV0IGRlIG5vcyB0cmF2YXV4LCBldCBvbiBsJ2EgZW5yZWdpc3RyZSBkYW5zIGxlIGRvc3NpZXIgZHUgcHJvamV0LiBMYSBwcm9jaGFpbmUgc2VjdGlvbiB2YSBlbiBkZXRhaWwgc3VyIGxlIHJtYXJrZG93biBldCBleHBsaXF1ZSB1biBwZXUgY29tbWVudCBpbCBlc3QgY29uY3UuCgoKCiMjIFByZXNlbnRhdGlvbiBldCBHZXN0aW9uIGR1IHJtYXJrZG93bgoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25ybWQiLz4KPC9hPgoKCiMjIyBIaXN0b3JpcXVlCgpDb21tZW50IGVzdCBuw6kgUiBNYXJrZG93bj8gW14zXSBEZSBsJ2lkw6llIGRlIGZhaXJlIGR1IHRleHRlIGV0IGR1IGNvZGUgUiBlbiBtw6ptZSB0ZW1wcyBkYW5zIHVuIG3Dqm1lIGZpY2hpZXIsIGRlIGZhw6dvbiByZXByb2R1Y3RpYmxlIGV0IGZhY2lsZW1lbnQgcGFydGFnZWFibGUuIExlIHBpb25uaWVyIGRlIGNldHRlIGlkw6llIGVzdCBZaWh1aSBYaWUsIHF1aSBzJ2VzdCBhcHB1ecOpIHN1ciBsJ2FuY8OqdHJlIGR1IHRyYXZhaWwgcmVwcm9kdWN0aWJsZSBgU3dlYXZlYCwgcXVpIHBlcm1ldHRhaXQgZGUgZmFpcmUgZHUgTGFUZVggZXQgZHUgUiBkYW5zIHVuIG3Dqm1lIGZpY2hpZXIsIGFmaW4gZGUgZmFjaWxpdGVyIGxhIHLDqWRhY3Rpb24gZGUgcmFwcG9ydHMgcXVpIG7DqWNlc3NpdGFpZW50IGxlcyBtw6ptZXMgdHlwZXMgZCdhbmFseXNlcy4gSWwgYSBsYW5jw6kgbGUgcGFja2FnZSBba25pdHJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9rbml0ci9pbmRleC5odG1sKSBzdXIgbGVxdWVsIHJlcG9zZSBsZSBwYWNrYWdlICpybWFya2Rvd24qLiBDJ2VzdCBsJ2Vzc2VudGllbC4gUiBNYXJrZG93biBlc3Qgc291dmVudCBwcsOpc2VudMOpIHNvdXMgbGEgZm9ybWUgc3VpdmFudGUsIG1ldHRhbnQgZW4gZXhlcmd1ZSBsZXMgZm9ybWF0cyBkZSBzb3J0aWUuCgohW11bT3V0cHV0Rm9ybWF0XQoKClBvdXIgY2V1eCBxdWkgc29udCBwcmVzc2VzIHN1ciBsYSBzeW50YXhlIGR1IG1hcmtkb3duIG91IGNhcnJlbWVudCB+fm4nb250IHBhcyBlbnZpZSBkZSBzZSB0YXBlcn5+IGxhIGxlY3R1cmUgZGUgdG91dCBsZSB0dXRvLApqZSB2b3VzIGNvbnNlaWxsZSBkZSBsaXJlIGxhIFtmZXVpbGxlIGRlIHRyaWNoZV0oaHR0cHM6Ly93d3cucnN0dWRpby5vcmcvbGlua3Mvcl9tYXJrZG93bl9jaGVhdF9zaGVldCkKZmFpdGUgcGFyICpSc3R1ZGlvKi4gVm91cyBwb3V2ZXogYWluc2kgc2F1dGVyIHRvdXRlIGNldHRlIHNlY3Rpb24gcG91ciBhbGxlciBsaXJlIGNlbGxlIHN1ciBsZSB0aWR5dmVyc2UgZXQgbGVzIHRlc3RzIHN0YXRpc3RpcXVlcy4KCgojIyMgUG91cnF1b2kgdXRpbGlzZXIgUiBNYXJrZG93biA/CgpgYGB7YmxvY2sgcXVvdGUtcmVwcm9kdWN0aWJpbGl0eSwgdHlwZSA9ICJtb250eXBlMiJ9CgoiV2hhdCBpcyBSZXByb2R1Y2liaWxpdHk/CiBSZXByb2R1Y2liaWxpdHkgaXMgb25lIG9mIHRoZSBtYWluIHByaW5jaXBsZXMgb2YgdGhlIHNjaWVudGlmaWMgbWV0aG9kLCBhbmQgcmVmZXJzIHRvIHRoZSBhYmlsaXR5IG9mIGEgdGVzdCBvciBleHBlcmltZW50IHRvIGJlIGFjY3VyYXRlbHkgcmVwcm9kdWNlZCwgb3IgcmVwbGljYXRlZCwgYnkgc29tZW9uZSBlbHNlIHdvcmtpbmcgaW5kZXBlbmRlbnRseS4iCiAKICoqWWlodWkgWGllKioKCmBgYAoKCkEgY2F1c2UgZGVzIHJhaXNvbnMgc3VpdmFudGVzOgoKMS4gTGEgcmVwcm9kdWN0aWJpbGl0ZS4gTCdpZGVlIGRlIGxhIHJlcHJvZHVjdGliaWxpdGUgZXN0IGRlIHBlcm1ldHRyZSBhIHRvdXQgdW4KY2hhY3VuIGRlIHBvdXZvaXIgcmVwcmVuZHJlIHNhIHByb3ByZSBldHVkZSBldCBzZXMgcHJvcHJlcyBhbmFseXNlcywgZW4gc3VpdmFudApleGFjdGVtZW50IGxlcyBtZW1lcyBldGFwZXMgcXVlIHNvaXQuCgoKMS4gUiBNYXJrZG93biBhIHVuZSBzeW50YXhlIGZhY2lsZSDDoCBtYcOudHJpc2VyOyBlbiBxdWVscXVlcyBtaW51dGVzIGQnZWZmb3J0IG9uIGFjcXVpZXJ0IGwnZXNzZW50aWVsIHBvdXIgw6ljcmlyZSBzb24gZG9jdW1lbnQuCgoyLiBBdmVjIHVuIHNldWwgZmljaGllciwgdm91cyBwb3V2ZXogYXZvaXIgcGx1c2lldXJzIGZvcm1hdHMgw6AgbGEgY2zDqSAoV29yZCwgUERGICjDoCBjb25kaXRpb24gZCdhdm9pciBMYVRlWCksIEhUTUwpCgoKMy4gQ2VsYSBwZXJtZXQgZGUgZmFjaWxpdGVyIGxlIHBhcnRhZ2UgZGUgZmljaGllcnMsIGwnZXhwbGljYXRpb24gZGVzIHNjcmlwdHMgZWZmZWN0dcOpcyBldCBsZSBwYXJ0YWdlIGF1IG5pdmVhdSBkZSBsYSBjb21tdW5hdXTDqSBzY2llbnRpZmlxdWUuCgpFdCBlbmZpbiwgb24gcGV1dCDDqWNyaXJlIHRvdXQgdW4gYXJ0aWNsZSBlbiBNYXJrZG93bi4KRmFpdGVzIHVuIHRvdXIgc3VyIFtsYSBHYWxsZXJpZSBkZSBybWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vZ2FsbGVyeS5odG1sKSBldCByZWdhcmRleiBsYSB2YXJpw6l0w6kgZGUgZG9jdW1lbnRzIHF1ZSBsJ29uIHBldXQgcsOpYWxpc2VyIGF2ZWMuCgoKIyMjIENyZWF0aW9uIGQndW4gZmljaGllciBybWFya2Rvd24KCk9uIGEgYXBwcmlzIGEgY3JlZXIgdW4gZmljaGllciBybWFya2Rvd24gc291cyAqUnN0dWRpbyouIFBvdXIgY2UgZmFpcmUsIGxhbmNleiBSIE1hcmtkb3duIGVuIGVmZmVjdHVhbnQgbGVzIHRhY2hlcyBzdWl2YW50ZXMgZGFucyBSIFN0dWRpbzoKCmBGaWxlPk5ldyBGaWxlPlIgTWFya2Rvd25gCgpJbCBhcHBhcmHDrnQgYWxvcnMgdW5lIGZlbsOqdHJlIGRlbWFuZGFudCBkZSBwcsOpY2lzZXIgbGVzIHBhcmFtw6h0cmVzIGR1IGZpY2hpZXIgcXVlIGwnb24gYSBjcsOpw6kuIElsIGZhdXQgcHJlY2lzZXIgbGUgdGl0cmUgZHUgZG9jdW1lbnQsIHNvbiBhdXRldXIgZXQgbGUgZm9ybWF0IGRlIHNvcnRpZS4gSWwgZXN0IHBvc3NpYmxlIGQnYXZvaXIgZHUgYHdvcmRgIChlbiBmYWl0IHVuIGAuZG9jeGApIG91IGR1IGBwZGZgIGNvbW1lIGZvcm1hdCBkZSBzb3J0aWUsIGplIHJldmllbmRyYWkgZGFucyBsYSBzZWN0aW9uIHN1ciBsYSBzb3J0aWUgYHBkZmAuIFBvdXIgbGEgdmVyc2lvbiB3b3JkLCBqZSB2b3VzIHJlbnZvaWUgYSBbbGEgZG9jdW1lbnRhdGlvbl0oKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vd29yZF9kb2N1bWVudF9mb3JtYXQuaHRtbCkpW142XS4gCgoKIVtdW1BhcmFtZXRyZV0KCgpVbmUgZm9pcyBsZXMgcGFyYW3DqHRyZXMgc3DDqWNpZmnDqXMsIG9uIHBldXQgcGFzc2VyIMOgIGwnYW5hbHlzZSBkdSBkb2N1bWVudCBiYXNpcXVlIHF1aSBzZXJ0IGRlIGTDqWJ1dCDDoCBsJ2FwcHJlbnRpc3NhZ2UgZHUgbGFuZ2FnZSBkZSBSIE1hcmtkb3duLiBJbCBzJ2FnaXQgZHUgZG9jdW1lbnQgc3VpdmFudDoKCjxjZW50ZXI+CiFbXVtGaWNoaWVyQmFzaXF1ZV0KPC9jZW50ZXI+CgojIyMgTCdlbi10w6p0ZSBkJ3VuIGRvY3VtZW50IFIgTWFya2Rvd24KCkwnZW4tdMOqdGUgZCd1biBkb2N1bWVudCBSIE1hcmtkb3duIGVzdCBjb25zdGl0dcOpIGRlIHBldGl0ZXMgcGhyYXNlcyBlbnRvdXLDqWVzIGQndW4gYC0tLWAsIGNvbW1lIGRhbnMgbGUgZG9jdW1lbnQgdXRpbGlzw6kgcG91ciBjcsOpZXIgY2UgZmljaGllciBxdWUgdm91cyBsaXNlejoKCmBgYAotLS0KdGl0bGU6ICJSw6ljYXBpdHVsYXRpZiBkZSBsYSBzw6lhbmNlIHRyb2lzIgphdXRob3I6ICJZdmVzIEFtZXZvaW4sIElTRSIKZGF0ZTogIk5vdmVtYnJlIDIwMTgiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY3NzOiBzdHlsZS5jc3MKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgdGhlbWU6IHlldGkKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGRwaTogNjAwCiAgICBkZXY6ICJwbmciCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCi0tLQpgYGAKCgpDZXQgZW5zZW1ibGUgZGUgcGhyYXNlcyAgY29udGllbnQgbGVzIGluZm9ybWF0aW9ucyBuw6ljZXNzYWlyZXMgYXUgcGFyYW3DqXRyYWdlIGR1IGRvY3VtZW50LiBMZSBkb2N1bWVudCBsdWkgbcOqbWUgcGV1dCDDqnRyZSBjb25zaWTDqXLDqSBjb21tZSB1biBlbnNlbWJsZSBkZSBkb25uw6llcyAoc2VjdGlvbiwgdGV4dGUsIGNvZGUgUiksIGV0IGxlcyBwYXJ0aWVzIHNpdHXDqWVzIGVudHJlIGNlcyBgLS0tYCwgZGVzIGluZm9ybWF0aW9ucyBkb25uYW50IGRlcyBhdHRyaWJ1dHMgZXQgZGVzIHBhcmFtw6h0cmVzIMOgIGNlcyBkb25uw6llcyAoY291bGV1ciwgdGl0cmUsIGRhdGUgZGUgY3LDqWF0aW9uLCBmb3JtYXQpOiBPbiBwYXJsZSBkZSAqKm3DqXRhZG9ubsOpZXMqKi4gQ2VzIGF0dHJpYnV0cyBkb2l2ZW50IMOqdHJlIHRyYW5zbWlzIMOgIHVuIGxhbmdhZ2UgcXVpIHNlIGNoYXJnZSBkZSBsZXMgc3RvY2tlciBldCBkZSBsZXMgcmVuZHJlIGF1IGRvY3VtZW50IHBvdXIgZW4gY2hhbmdlciBsJ2FzcGVjdCBvdSBham91dGVyIGRlcyBpbmZvcm1hdGlvbnMuIENlIGxhbmdhZ2UsIGMnZXN0IGxlICoqWUFNTCoqIHF1aSBzaWduaWZpYWl0IGF1IGTDqWJ1dCBfWWV0IEFub3RoZXIgTWFya3VwIExhbmd1YWdlXyBtYWlzIHF1aSBlc3QgZGV2ZW51IF9ZQU1MIEFpbnQgTWFya3VwIExhbmd1YWdlXy4gRW4gY2xhaXIgbGUgKipZQU1MKiogYydlc3QgcXVvaT8gVW5lIHN5bnRheGUgcXVpIHBlcm1ldCBkZSBzdG9ja2VyIGRlcyBkb25uw6llcyBzdXIgbGUgZG9jdW1lbnQgZXQgcXVpIGxlcyB1dGlsaXNlIHBvdXIgcGFyYW3DqXRyZXIgbGUgZG9jdW1lbnQgUiBNYXJrZG93biBldCB5IGFqb3V0ZXIgZGVzIGNob3Nlcy4gQ2V0dGUgc3ludGF4ZSBlc3QgdHLDqHMgc3RyaWN0ZSwgYXZlYyBkZXMgZGV1eCBwb2ludHMsIGRlcyByZXRvdXJzIMOgIGxhIGxpZ25lLCBkZXMgZ3VpbGxlbWV0cyBldCBkZXMgaW5kZW50YXRpb25zIChwZXRpdHMgZXNwYWNlcyBhcHLDqHMgbGUgcmV0b3VyIMOgIGxhIGxpZ25lKSBwb3VyIGNpYmxlciBsZXMgc291cy1vcHRpb25zIGQndW5lIG9wdGlvbiBtZXJlLiBQYXIgZXhlbXBsZSwgcG91ciBsZSBgaHRtbF9kb2N1bWVudGAgcXVpIHNpZ25pZmllIGxlIGZvcm1hdCBkZSBzb3J0aWUsIG9uIGEgZGVtYW5kZSBkJ2luY2x1cmUgdW5lIHRhYmxlIGRlcyBtYXRpZXJlcyAoYHRvYzp5ZXNgKSwgbGEgcG9zc2liaWxpdGUgZGUgdGVsZWNoYXJnZXIgbGVzIGNvZGVzIGR1IGRvY3VtZW50IChgY29kZV9kb3dubG9hZCA6IFRSVUVgKS4gTGVzIG9wdGlvbnMgc29udCBlbiBnZW5lcmFsIGxpZWVzIGF1eCBmb3JtYXQgZGUgc29ydGllIGxpZWVzIGF1IGRvY3VtZW50IHF1ZSB2b3VzIHZvdWxleiBvYnRlbmlyLiBDb21tZW50IGxlcyBkb25uw6llcyBzdXIgbGUgZG9jdW1lbnQgc29udCBzdG9ja8OpZXM/IERhbnMgdW4gb2JqZXQgYXBwZWzDqSBgbWV0YWRhdGFgIGRhbnMgbGUgcGFja2FnZSBgcm1hcmtkb3duYC4gUmVnYXJkZXo6CgpgYGB7ciBtZXRhZGF0YX0Kcm1hcmtkb3duOjptZXRhZGF0YSR0aXRsZQpgYGAKCgpQb3VyIHVuIGRvY3VtZW50IEhUTUwsIGlsIGV4aXN0ZSB1bmUgcGzDqXRob3JlIGRlIHBhcmFtw6h0cmVzIChhdXRldXIsIGRhdGUsIGZvbnRlLCBldGMuKSBldCBsJ29uIHBldXQgbcOqbWUgYWpvdXRlciB1biBmaWNoZXIgcXVpIHByZW5kIGJpZW4gZW4gY2hhcmdlIGxhIG1pc2UgZW4gZm9ybWUsIGNvbW1lIG1vbiBmaWNoaWVyIGBzdHlsZS5jc3NgIHF1ZSB2b3VzIHZveWV6IGRhbnMgbCdvcHRpb24gYGNzc2AuIE9uIHBldXQgZW4gZmFpcmUgZGUgbcOqbWUgYXZlYyB1biBmaWNoaWVyIFBERi4gT24gcG91cnJhaXQgw6ljcmlyZSB1biBhcnRpY2xlIGRlc3N1cy4gTWFpcyBlbiBnw6luw6lyYWwgbGUgcGV0aXQgbm9tYnJlIGRlIHBhcmFtw6h0cmVzIHBhciBkw6lmYXV0IHByb3Bvc8OpIHBhciAqUnN0dWRpbyogc3VmZml0IGFtcGxlbWVudCBwb3VyIGRlcyBkb2N1bWVudHMgZGUgcGV0aXRlIGVudmVyZ3VyZS4gRGFucyBsZSBjYXMgb8O5IHZvdXMgdm91bGV6IGRlcyBkb2N1bWVudHMgbG91cmRzLCBpbCBzZXJhaXQgIHNvdWhhaXRhYmxlIGRlIGpldGVyIHVuIGNvdXAgZOKAmcWTaWwgc3VyIGxlcyBwYWdlcyBzdWl2YW50ZXMgYWZpbiBkZSByZWdhcmRlciBjb21tZW50IGNvbnRyw7RsZXIgbGEgbWlzZSBlbiBwYWdlOgoKKiBQb3VyIGxlIGZvcm1hdCBIVE1MLCBbUmVnYXJkZXogaWNpXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL2h0bWxfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoqIFBvdXIgbGUgZm9ybWF0IFBERiwgW1JlZ2FyZGV6IGzDoF0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS9wZGZfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoqIFBvdXIgbGUgZm9ybWF0IFdvcmQsIFtKZXR0ZXogdW4gY291cCBkJ29laWwgbMOgXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL3dvcmRfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoKIyMjIExlcyBjaHVua3MKClVuIGZpY2hpZXIgYHJtYXJrZG93bmAgZXN0IHVuICBmaWNoaWVyIGRhbnMgbGVxdWVsIHNlIHRyb3V2ZW50IGxlcyBjb2RlcyBxdWkgdm9udApwZXJtZXR0cmUgZGUgZ2VuZXJlciBsZXMgYW5hbHlzZXMgZXQgbGVzIHJlc3VsdGF0cyBhc3NvY2llcyBhdXggYW5hbHlzZXMgcHJvcHJlbWVudCAKZGl0ZXMgYWluc2kgcXVlIGxlcyBjb21tZW50YWlyZXMgZGUgY2VzIGFuYWx5c2VzLiBDZXMgY29kZXMgc2UgdHJvdXZlbnQgZGFucyAKZGVzIHBvcnRpb25zIGdyaXNlcyBhcHBlbGVlcyAqKmNodW5rKiosIGFmaW4gZGUgbGVzIGRpc3Rpbmd1ZXIgZGVzIGNvbW1lbnRhaXJlcyAKLSBkdSB0ZXh0ZSBicnV0IC0gcXVlIHZvdXMgZWNyaXZlei4gQ29tbWVudCBpbnNlcmVyIHVuIGNodW5rIGxvcnNxdWUgbCdvbiB0cmF2YWlsbGUKc291cyAqUnN0dWRpbyo/ICoqUG91ciBpbnNlcmVyIHVuIGNodW5rIFIgc291cyBfUnN0dWRpb18sIHV0aWxpc2V6IGxlIHJhY2NvdXJjaSAKY2xhdmllciBgQ1RSTCtBTFQrSWAqKi4gTWFpcyBzaSB2b3VzIHZvdWxleiB+fnZvdXN+fiB0YXBlciBsYSBzeW50YXhlIGRlIApsJ2Vjcml0dXJlLCB1biBjaHVuayBjb21tZW5jZSBwYXIgY2VzIHRyb2lzIGFjY2VudHMgZ3JhdmVzIGBgYGAgYGBgIGBgYGAgc3VpdmlzIApkZSByIHF1ZSBsJ29uIG1ldCBlbnRyZSBkZXMgYWNjb2xhZGVzLCBgYGBgIGBgYHtyfSBgYGBgIGV0IGlsIHNlIHRlcm1pbmUgcGFyIHRyb2lzCmFjY2VudHMgZ3JhdmVzIGF1c3NpIGBgYGAgYGBgIGBgYGAuIFVuZSBlcnJldXIgY29tbXVuZSBlc3QgZGUgbmUgcGFzIHRlcm1pbmVyCnNvbiBjaHVuayBvdSBkJ2VmZmFjZXIgcGFyIG1hbGFkcmVzc2UgbGVzIHRyb2lzIGFjY2VudHMgZGUgbGEgZmluLiAKCkxlcyBjaHVuayBwZXV2ZW50IGF2b2lyIGRlcyBvcHRpb25zIGVuIGZvbmN0aW9uIGRlIGNvbW1lbnQgbCdvbiB2ZXV0IHRyYWl0ZXIgbGUgCnJlbmR1LiBFbiBnZW5lcmFsIG9uIHBldXQgc29pdCB2b3Vsb2lyIGFmZmljaGVyIGxlIGNvZGUgb3UgcGFzLCBzb2l0IGxhIHNvcnRpZSAKZHUgY29kZSBvdSBwYXMsIHNvaXQgZXZhbHVlciBsZSBjb2RlIG91IHBhcy4gVm91cyBwb3V2ZXogcGFyY291cmlyIGxlcyBvcHRpb25zIApkJ3VuIGNodW5rIFIgcXVlIHZvdXMgYXVyZXogaW5zZXJlIGVuIGNsaXF1YW50IHN1ciBsZXMgcGFyYW1ldHJlcyBkdSBjaHVuay4KCjxjZW50ZXI+CiFbXVtDaHVua1BhcmFtZXRlcnNdCjwvY2VudGVyPgoKVW5lIGZvaXMgcXVlIHZvdXMgdmVycmV6IGNvbW1lbnQgbGVzIG9wdGlvbnMgb250IGV0ZSBpbnNlcmVlcywgdm91cyBwb3V2ZXogdGFwZXIKbGUgY29kZSB2b3VzIG1lbWUuIE9uIGEgZG9uYyByZWNoYXJnZSBub3RyZSBiYXNlIGRlIGRvbm5lZXMgZW4gdXRpbGlzYW50IApsZSBjaHVuayBzdWl2YW50OgoKPGNlbnRlcj4KIVtdW0NodW5rSW5zZXJ0aW9uXQo8L2NlbnRlcj4KCiAgICAgICAgCkxlcyBjaHVua3MgcGFyIGRlZmF1dCwgc3VwcG9zZW50IHF1ZSB2b3VzIGF2ZXogZHUgUiBjb21tZSBsYW5nYWdlLCBtYWlzIGlsIGVzdCBwb3NzaWJsZSBkZSBjcmVlciBkZXMgY2h1bmNrcyBhdmVjIGQnYXV0cmVzIGxhbmdhZ2VzLiAgVm91cyBwb3V2ZXogY2hvaXNpciBsZSBsYW5nYWdlIGFzc29jaWUgYXUgY2h1bmsgCnF1ZSB2b3VzIHZvdWxleiBpbnNlcmVyIGVuIGNsaXF1YW50IHN1ciAqKmluc2VydCoqIGVuIGhhdXQgYSBnYXVjaGUgZGUgbCdlZGl0ZXVyLiBFbiBiYXMgcGFyIGV4ZW1wbGUsIGonaW5zZXJlIHVuIGNodW5rIGF2ZWMgZGVzIGNvbW1hbmRlcyBzeXN0ZW1lcy4KCjxjZW50ZXI+CiFbXVtDaHVua0VuZ2luZV0KPC9jZW50ZXI+CgpgYGB7YmFzaCBjaHVua3MtYmFzaH0KY2Qgfi9Eb2N1bWVudHMKbHMKCmBgYAoKClNpIHZvdXMgZmFpdGVzIGRlIG1lbWUsIHZvdXMgdmVycmV6IHF1ZSB2b3RyZSBjaHVuayBjb21tZW5jZSBwYXIgYGBgYCBgYGB7YmFzaH0gYGBgYC4KQ2VsYSBwZXJtZXQgYSBrbml0ciBkZSBzYXZvaXIgcXVlbCBsYW5nYWdlIHV0aWxpc2UgZGFucyBsZSBjaHVuay4gCgpMZXMgY2h1bmsgcGV1dmVudCBhdm9pciB1biBub20uIEwnaWRlZSBlc3QgZGUgbGV1ciBwZXJtZXR0cmUgZCdldHJlIGZhY2lsZW1lbnQgCmFjY2Vzc2libGUgZW4gdXRpbGlzYW50IGxlcyBvbmdsZXRzIGRlIG5hdmlnYXRpb24gZGUgKlJzdHVkaW8qLiBQb3VyIG5vbW1lciB1biAKY2h1bmssIGlsIHN1ZmZpdCBkZSBtZXR0cmUgCgojIyMgTGUgY2h1bmsgc2V0dXAKCiMjIyBEZXMgbGlzdGVzIGV0IGRlcyBmb3JtdWxlcwoKT24gcGV1dCBmYWlyZSBkZXMgbGlzdGVzIGF2ZWMgdW4gZmljaGllciBSIE1hcmtkb3duIGRlIGZhw6dvbiB0csOocyBmYWNpbGU6CgpgYGAKVW5lIGxpc3RlIG51bcOpcm90w6llOgoKMS4gVW4KMi4gRGV1eAozLiBUcm9pcwozLiBRdWF0cmUKClZvdXMgcmVtYXJxdWVyZXogcXUnaWwgYXVnbWVudGUgZW4gbcOqbWUgdGVtcHMgbGUgY2hpZmZyZSBub24/CgpFdCBkZXMgbGlzdGVzIG5vbiBudW3DqXJvdMOpZXMgY29tbWUgYXZlYyBkZXMgdGlyZXRzOgoKLSBVbgotIERldXgKLSBUcm9pcwoKT3UgYXZlYyBkZXMgcG9pbnRzOgoKKiBVbgoqIERldXgKKiBUcm9pcwoKT3UgbGVzIGRldXg6CgoqIEonYWltZSBsYSBiaW9zdGF0aXN0aXF1ZQogICAgKyBMZXMgZWxldmVzIG4nb250IHBhcyBpbnN0YWxsZXIgbGVzIHBhY2thZ2VzCiAgICArIENvdWNvdSBhIHRvdXMuCiAgCiogSWwgc2FpdCBtZXR0cmUgbGEgZGlmZsOpcmVuY2UgZW50cmUgbGVzIHJvbmRlcyBibGFuY2hlcyBldCBsZXMgbm9pcmVzLiBJbCBzdWZmaXQgZCdhbGxlciDDoCBsYSBsaWduZSBldCBkZSBtZXR0cmUgZGV1eCBpbmRlbnRhdGlvbnMgYXZlYyBsZSBgYmFja3NwYWNlYCAobCdhY2NlbnQgZ3JhdmUgZXN0IHBvdXIgbWV0dHJlIGVuIGV4ZXJndWUpIHBvdXIgYXZvaXIgZGVzIHNvdXMtbGlzdGVzLgpgYGAKCkxlIHRleHRlIHByw6ljw6lkZW50IGRvbm5lIGxhIHNvcnRpZSBzdWl2YW50ZToKCmBgYHtibG9jaywgdHlwZT0gIm1vbnR5cGUyIn0KVW5lIGxpc3RlIG51bcOpcm90w6llOgoKMS4gVW4KMi4gRGV1eAozLiBUcm9pcwozLiBRdWF0cmUKClZvdXMgcmVtYXJxdWVyZXogcXUnaWwgYXVnbWVudGUgZW4gbcOqbWUgdGVtcHMgbGUgY2hpZmZyZSBub24/CgpFdCBkZXMgbGlzdGVzIG5vbiBudW3DqXJvdMOpZXMgY29tbWUgYXZlYyBkZXMgdGlyZXRzOgoKLSBVbgotIERldXgKLSBUcm9pcwoKT3UgYXZlYyBkZXMgcG9pbnRzOgoKKiBVbgoqIERldXgKKiBUcm9pcwoKT3UgbGVzIGRldXg6CgoqIEonYWltZSBsYSBiaW9zdGF0aXN0aXF1ZQogICAgKyBMZXMgZWxldmVzIG4nb250IHBhcyBpbnN0YWxsZXIgbGVzIHBhY2thZ2VzCiAgICArIENvdWNvdSBhIHRvdXMuCiAgCiogSWwgc2FpdCBtZXR0cmUgbGEgZGlmZsOpcmVuY2UgZW50cmUgbGVzIHJvbmRlcyBibGFuY2hlcyBldCBsZXMgbm9pcmVzLiBJbCBzdWZmaXQgZCdhbGxlciDDoCBsYSBsaWduZSBldCBkZSBtZXR0cmUgZGV1eCBpbmRlbnRhdGlvbnMgYXZlYyBsZSBgYmFja3NwYWNlYCBwb3VyIGF2b2lyIGRlcyBzb3VzLWxpc3Rlcy4KCmBgYAoKLS0tCgpPbiBwZXV0IGZhaXJlIGR1IHBkZiBiYXNlIHN1ciBkdSAkXExhVGVYJCBkYW5zIHJtYXJrZG93biwgY29tbWUgamUgbCdhdmFpcyBkaXQgZW4gbW9udHJhbnQgY2V0dGUgaW1hZ2UgW2ljaV1bT3V0cHV0Rm9ybWF0XS4KPGEgbmFtZT0ibGllbnZlcnNsZWhhdXQiLz4KPC9hPgpPbiBwZXV0IGluc8OpcmVyIGRlcyBmb3JtdWxlcyAkXExhVGVYJCBkYW5zIHVuIGRvY3VtZW50IFIgTWFya2Rvd24gcGV1IGltcG9ydGUgbGUgZm9ybWF0IGRlIHNvcnRpZSwgZW4gdXRpbGlzYW50IGxhIG3Dqm1lIHN5bnRheGUgcXVlIGNlbGxlIGRlIExhVGVYOgoKYGBgCiRcc3VtX3tpPTF9Xm5cYWxwaGFfaSQ7CgokdGFuKHgpPVxmcmFje2Nvcyh4KX17c2luKHgpfSQKYGBgCgoKYGBge2Jsb2NrLCB0eXBlPSJtb250eXBlMiJ9CiRcc3VtX3tpPTF9Xm5cYWxwaGFfaSQ7CgokdGFuKHgpPVxmcmFje2Nvcyh4KX17c2luKHgpfSQKYGBgCgoKIyMjIEluc8OpcmVyIGRlcyBJbWFnZXMsIEluc8OpcmVyIGRlcyB0YWJsZWF1eAoKTGUgZmljaGllciBxdWUgdm91cyBsaXNleiBlc3QgcGxlaW4gZCdpbWFnZXMgcXVpIHBlcm1ldHRlbnQgZCdpbGx1c3RyZXIgbGVzIHByb3Bvcy4gT24gcGV1dCBpbnPDqXJlciBkZXMgaW1hZ2VzIGRhbnMgdW4gZmljaGllciBSIE1hcmtkb3duLiBQb3VyIGNlbGEgaWwgZmF1dCBkb25uZXIgdW4gaWRlbnRpZmlhbnQgw6AgbCdpbWFnZSAoY29tbWUgcGFyIGV4ZW1wbGUgYG1vbmltYWdlYCkgZXQgbOKAmWluc8OpcmVyIGRhbnMgbGUgZG9jdW1lbnQgZGUgbGEgZmHDp29uIHN1aXZhbnRlOgoKYGBgCiFbTGUgdGl0cmUgZGUgbCdpbWFnZV1bbW9uaW1hZ2VdCmBgYAoKTWFpcyBjb21tZW50IFIgTWFya2Rvd24gcmV0cm91dmUgbCdpbWFnZSBjb3JyZXNwb25kYW50ZT8gRW4gbWV0dGFudCDDoCAqKmxhIGZpbiBkdSBmaWNoaWVyKiogbGVzIHLDqWbDqXJlbmNlcyBwZXJtZXR0YW50IGQnYXR0ZWluZHJlIGwnaW1hZ2UuIExhIHN5bnRheGUgZXN0IGxhIHN1aXZhbnRlIHBvdXIgdW4gZm9ybWF0IHBuZyBwYXIgZXhlbXBsZS4KCmBgYApbbW9uaW1hZ2VdOiBDaGVtaW5fdmVyc19saW1hZ2UvaW1hZ2UucG5nICJUZXh0ZSBwb3B1cCBxdWkgcydhZmZpY2hlIHF1YW5kIGxhIHNvdXJpcyBzdXJ2b2xlIgpgYGAKCkwnaWRlbnRpZmlhbnQgcGV1dCDDqnRyZSB1dGlsaXPDqSBwb3VyIGluZGV4ZXIgbCdpbWFnZSDDoCB0cmF2ZXJzIHVuIGxpZW4gZGFucyBsZSBkb2N1bWVudCwgY29tbWUgaidhaSBmYWl0IHBvdXIgW2ljaV0oI2xpZW52ZXJzbGVoYXV0KQoKIyMjIyBMZXMgVGFibGVhdXgKCklsIGV4aXN0ZSBwbHVzaWV1cnMgbWFuacOocmVzIGQnaW5zw6lyZXIgdW4gdGFibGVhdSwgbGEgZmHDp29uIGxhIHBsdXMgcmVjb21tYW5kw6llIMOpdGFudCBkJ3V0aWxpc2VyIGxlIHBhY2thZ2UgYGtuaXRyYCBjb21tZSBwcsOpc2VudMOpIFtwcsOpY8OpZGVtbWVudF0oI2xpZW52ZXJzbGV0YWJsZWF1KS4gCkNlcGVuZGFudCwgaWwgZXN0IHBvc3NpYmxlIGQnaW5zw6lyZXIgdW4gdGFibGVhdSBkYW5zIHVuIGRvY3VtZW50IFIgTWFya2Rvd24gZGUgbGEgZmHDp29uIHN1aXZhbnRlLCBvdSBsZXMgZGV1eCBwb2ludHMgcGVybWV0dGVudCBkZSBkaXJlIGNvbW1lbnQgbCdvbiB2ZXV0IGFsaWduZXIgbGVzIGVsZW1lbnRzIGR1IHRhYmxlYXUuCgpgYGAKOiBVbiBUYWJsZWF1Cgp8QWxpZ27DqSDDoCBEcm9pdGV8QWxpZ27DqSDDoCBHYXVjaGV8UGFyIETDqWZhdXR8QXUgQ2VudHJlfAp8LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfDotLS0tLS0tOnwKfEluc3RhbGxleiAgICAgIHxOJ291YmxpZXogcGFzICB8UGFja2FnZSAgICB8IGxlcyAgICAgfAp8bGVzICAgICAgICAgICAgfERpbnN0YWxsZXIgICAgIHxJbnN0YWxsZXogIHxwYWNrYWdlICAgIHwKfHBhY2thZ2UgICAgICAgIHxsZXMgICAgICAgICAgICB8YXZhbnQgZGUgdmVuaXJ8NSAgICAgIHwKCgoKYGBgCgpgYGB7YmxvY2ssIHR5cGU9Im1vbnR5cGUyIn0KOiBVbiBUYWJsZWF1Cgp8QWxpZ27DqSDDoCBEcm9pdGV8QWxpZ27DqSDDoCBHYXVjaGV8UGFyIETDqWZhdXR8QXUgQ2VudHJlfAp8LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfDotLS0tLS0tOnwKfEluc3RhbGxleiAgICAgIHxOJ291YmxpZXogcGFzICB8UGFja2FnZSAgICB8IGxlcyAgICAgfAp8bGVzICAgICAgICAgICAgfERpbnN0YWxsZXIgICAgIHxJbnN0YWxsZXogIHxwYWNrYWdlICAgIHwKfHBhY2thZ2UgICAgICAgIHxsZXMgICAgICAgICAgICB8YXZhbnQgZGUgdmVuaXJ8NSAgICAgIHwKCmBgYAoKLS0tCgojIyMgTGVzIHBldGl0cyBwbHVzIHBvdXIgZmluaXIKCiMjIyMgVW4gZmljaGllciBjb21tZSBjZWx1aS1jaSAuLi4gT24gZmFpdCBjb21tZW50PwoKUG91ciBjcsOpZXIgdW4gZmljaGllciBjb21tZSBjZWx1aS1jaSwgcmllbiBkZSBwbHVzIHNpbXBsZSEgQ3LDqWV6IHVuIGRvY3VtZW50IFIgTWFya2Rvd24gbm9ybWFsIGV0IGFqb3V0ZXogcXVlbHF1ZXMgcGFyYW3DqHRyZXMgcG91ciBsZSByZW5kcmUgcGx1cyBhdHRyYWN0aWYuIEonYWkgZCdhYm9yZCBjaGFuZ8OpIGxlIHRow6htZSBnw6luw6lyYWwgZW4gY2hvaXNpc3NhbnQgbGUgdGjDqG1lIGBmbGF0bHlgIHF1ZSBqJ2FpbWUgYmllbi4gUG91ciBjZWxhLCBpbCBmYXV0IGFqb3V0ZXIgbGEgc3ludGF4ZSBgdGhlbWU6IGZsYXRseWAgZGFucyBsZSBibG9jICoqWUFNTCoqLiBKJ2FpIGF1c3NpIGFqb3V0ZXIgbGEgdGFibGUgZGVzIG1hdGnDqHJlcywgYWluc2kgcXUndW4gZMOpZmlsZW1lbnQgcGx1dMO0dCBpbnTDqXJlc3NhbnQgZGUgbGEgdGFibGU6CgpgYGAKLS0tCiMgTGUgaGF1dCBkZSBsYSBzeW50YXhlCnRvYzogdHJ1ZQp0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKLS0tCmBgYAoKTGEgbWlzZSBlbiBmb3JtZSBkZSBsYSBwYWdlIGV0IGxlIHN0eWxlIG9udCDDqXTDqSBnw6lyw6lzIGF2ZWMgdW4gZmljaGllciBkZSBjb25maWd1cmF0aW9uLCBhcHBlbMOpIGBzdHlsZS5jc3NgLiBBIHF1b2kgc2VydCB1biBmaWNoaWVyIC5jc3M/IEEgZMOpZmluaXIgbGEgbWlzZSBlbiBwYWdlIGRlIHBhZ2VzIHdlYi4gSidhaSBqdXN0ZSB1dGlsaXPDqSBxdWVscXVlcyBicmliZXMgZGUgY29ubmFpc3NhbmNlIGRhbnMgbGUgZG9tYWluZSBwb3VyIGfDqXJlciBsYSBtaXNlIGVuIHBhZ2UuIExlIGNzcyBwZXV0IMOgIGx1aSB0b3V0IHNldWwgZmFpcmUgbCdvYmpldCBkJ3VuIGF1dHJlIGZpY2hpZXIgdHV0b3JpZWwuIE1haXMgcGFzIGJlc29pbiBkZSBncmFuZCBjaG9zZXMgcG91ciB1bmUgbWlzZSBlbiBmb3JtZSBjb21tZSBjZWxsZSB1dGlsaXPDqWUgZGFucyBjZSBkb2N1bWVudC4gSWwgc3VmZml0IGp1c3RlIGRlIFtqZXRlciB1biBjb3VwIGQnb2VpbF0oc3R5bGUuY3NzKSBzdXIgbW9uIGZpY2hpZXIgcG91ciB2b3VzIGVuIHJlbmRyZSBjb21wdGUuIERhbnMgbGUgZmljaGllciBjc3MsYGJvZHlgIHJlcHLDqXNlbnRlIGxlIGNvcnBzIGR1IGRvY3VtZW50IGV0IGxlcyBwcm9wcmnDqXTDqXMgZMOpZmluaXNzZW50IGNvbW1lbnQgbGUgZG9jdW1lbnQgZXN0IGZvcm1hdMOpLiBBaW5zaSwgbW9uIGRvY3VtZW50IGVzdCBtaXMgZW4gZm9udGUgR2VvcmdpYSwgMTNwdCwgZXQgICoqanVzdGlmacOpKiogYXZlYyBsYSBzeW50YXhlIHN1aXZhbnRlOgoKYGBgCmJvZHl7CiAgZm9udC1mYW1pbHk6IEdlb3JnaWE7CiAgZm9udC1zaXplOiAxM3B0OwogIHRleHQtYWxpZ246IGp1c3RpZnk7Cn0KYGBgCgpgaDFgLCBgaDJgLCBgaDNgIGTDqXNpZ25lbnQgbGVzIHNlY3Rpb25zIGV0IHNvdXMgc2VjdGlvbnMgZGUgbml2ZWF1eCAxLDIsMyByZXNwZWN0aXZlbWVudC4gSidhaSBnw6lyw6kgYXVzc2kgbGEgbWlzZSBlbiBmb3JtZSBkZSBjZXJ0YWlucyBibG9jcyBkYW5zIGxlIGZpY2hpZXIgY3NzLiBDZWxhIGZlcmEgbCdvYmpldCBkZSBsYSBzZWN0aW9uIHN1aXZhbnRlLiBQb3VyIHBsdXMgZCdpbmZvcm1hdGlvbnMgc3VyIGxlIGNzcywgcmVuZGV6LXZvdXNbXjRdIHN1ciBsYSBwYWdlIFtsw6BdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2ZyL0FwcHJlbmRyZS9DU1MpLiBSZXN0ZSDDoCBpbmNsdXJlIGxlIGZpY2hpZXIgZGFucyBsZSBkb2N1bWVudCDDoCB0cmF2ZXJzIGxhIHN5bnRheGUgKipZQU1MKiogYGNzczogc3R5bGUuY3NzYCBhcHLDqHMgbCdhdm9pciBtaXMgZGFucyBsZSBtw6ptZSByw6lwZXJ0b2lyZSBxdWUgbGUgZmljaGllciBSIE1hcmtkb3duLgoKIyMjIyBMYSBtaXNlIGVuIGZvcm1lIGRlcyBibG9jcwoKTGEgbWlzZSBlbiBmb3JtZSBkZXMgYmxvY3Mgcydlc3QgZmFpdGUgZW4gdXRpbGlzYW50IGF1c3NpIGR1IGBjc3NgLiAgTGUgcGFja2FnZSBga25pdHJgIHBlcm1ldCBkJ2luc8OpcmVyIGQnYXV0cmVzIGxhbmdhZ2VzIHF1ZSBkdSBSIGRhbnMgbGVzIGJsb2NzIGRlIGNvZGUgKipldCBtw6ptZSBkZSBsZXMgZXjDqWN1dGVyIMOgIHRyYXZlcnMqKiB1biBzeXN0w6htZSBub21tw6kgW2VuZ2luZV0oaHR0cHM6Ly95aWh1aS5uYW1lL2tuaXRyL2RlbW8vZW5naW5lcy8pLiBJbCBlc3QgYXVzc2kgcG9zc2libGUgZGUgY3LDqWVyIGRlcyBibG9jcyB2aWRlcywgbm9uIGNvbmZvcm1lcyDDoCB1biBsYW5nYWdlIHByw6ljaXMgb3UgZGVzIGJsb2NzIHByb3ByZXMgZm9ybWF0w6lzIGVuIE1hcmtkb3duLiBDJ2VzdCBjZSBxdWkgYSDDqXTDqSBmYWl0IGRhbnMgbGVzIGJsb2NzIGVuIG1hcnJvbiBkYW5zIGxlIGRvY3VtZW50LiBQb3VyIGNyw6llciB1biBibG9jIHByb3ByZSBlbiBNYXJrZG93biwgZGFucyBsZSBmaWNoaWVyIFIgTWFya2Rvd24gb24gw6ljcml0IHVuIGJsb2Mgc3VpdmFudDoKCgpgYGAKYGBgYHtibG9jaywgdHlwZT0idW50eXBlIn0KbiA9IDEwCnJub3JtKG4pCmBgYGAKYGBgCgpJbCBmYXV0IGVuc3VpdGUgZmFpcmUgbGEgbWlzZSBlbiBmb3JtZSBlbiB5IGRhbnMgam9pZ25hbnQgbGUgZmljaGllciBgLmNzc2AgbGEgZm9ybWUgZMOpZGnDqWUgYXUgYmxvYyBgdW50eXBlYC4gRGFucyBsZSBmaWNoaWVyIGAuY3NzYCwgb24gcG91cnJhIGRvbmMgw6ljcmlyZSBsZXMgYmxvY3MgZGUgY29kZSBzdWl2YW50czoKCmBgYAoudW50eXBlewogIGJhY2tncm91bmQtY29sb3I6ICNmOWY1ZjM7CiAgZm9udC1zaXplOjEycHQ7CiAgZm9udC1mYW1pbHk6ICJHZW9yZ2lhIiwgc2VyaWY7CiAgcGFkZGluZy10b3A6NXB4OwogIHBhZGRpbmctbGVmdDo4cHg7CiAgYm9yZGVyLWxlZnQ6IDVweCBzb2xpZCAjZThkYWQxOwogIHBhZGRpbmctYm90dG9tOjVweDsKICBwYWRkaW5nLXJpZ2h0OjVweDsKfQpgYGAKCkFpbnNpLCDDoCBjaGFxdWUgZm9pcyBxdWUgbCdvbiBjaG9pc2lyYSB1biBibG9jIGRlIHR5cGUgYHVudHlwZWAsIGlsIGF1cmEgbGVzIHByb3ByacOpdMOpcyBjaXTDqXMgcGx1cyBoYXV0LgoKCiMjIyMgRXQgcG91ciB1biBkb2N1bWVudCBsb3VyZD8gT3UgdW4gYXJ0aWNsZT8KCgoKTidleGFnw6lyb25zIHJpZW4sIG1lIGRpcmV6LXZvdXMuLi4uIFBvdXJxdW9pIHLDqWRpZ2VyIHVuIGxpdnJlIGVudGllciBvdSB1biBhcnRpY2xlIGRhbnMgKlJzdHVkaW8qIGFsb3JzIHF1J29uIGEgV29yZD8KCioqUGFyY2UgcXVlIGMnZXN0IHJlcHJvZHVjdGlibGUqKgoKVm91cyB2b3VzIHJlbmRlei1jb21wdGUgZCd1bmUgZXJyZXVyPyBVbmUgbW9kaWZpY2F0aW9uIGV0IMOnYSB5IGVzdCEgdG91dCBlc3QgcsOpZ2zDqS4gUGFzIGRlIGNvcGllciBjb2xsZXIgYXZlYyBkZXMgcGVydGVzIGRlIHRlbXBzIGV0IGRlcyByaXNxdWVzIGQnZXJyZXVycy4gQXVzc2ksIHZvdXMgcG91dmV6IGp1c3RlIGJhbGFuY2VyIGxlIGNvZGUgw6AgdW4gYW1pIGV0IGlsIHBldXQgcmVwcmVuZHJlIGxlcyBtw6ptZXMgYW5hbHlzZXMgZXQgb2JzZXJ2ZXIgc2kgdm91cyBhdmV6IHRvdXQgYmllbiBmYWl0LCBvdSBsb3VwZXogcXVlbHF1ZSBjaG9zZS4uLiDDh2EgbidhcnJhbmdlIHF1ZSBsYSByZWNoZXJjaGUuCgpSZXZlbm9ucyBhdSB0aXRyZSwgY29tbWVudCByw6lkaWdlciB1biBhcnRpY2xlIHNvdXMgUiBNYXJrZG93bi4gTG9yc3F1ZSB2b3VzIGTDqWNpZGV6IGRlIGNyw6llciB1biBub3V2ZWF1IGRvY3VtZW50IHNvdXMgUiBNYXJrZG93biwgdm91cyBhdmV6IHVuZSBwYWdlIHN1aXZhbnRlIGNvcnJlc3BvbmRhbnQgYXUgZG9jdW1lbnQgcXVlIHZvdXMgdm91bGV6OgoKIVtdW1RlbXBsYXRlXQoKRW4gYmFzLCB2b3VzIHBvdXZleiBjaG9pc2lyIGwnb3B0aW9uIF9Gcm9tIFRlbXBsYXRlXyBwb3VyIGNyw6llciBsZSBkb2N1bWVudCDDoCBwYXJ0aXIgZCdleGVtcGxhaXJlcyBleGlzdGFudCBkw6lqw6AuIENldHRlIHNlY3Rpb24gbm91cyBwZXJtZXQgZGUgY2hvaXNpciB1biBlbnNlbWJsZSBkJ2V4ZW1wbGFpcmVzIGV0IGRlIGxlcyB1dGlsaXNlciDDoCBvdXRyYW5jZSBsb3JzcXVlIHZvdXMgc291aGFpdGV6IGZhaXJlIHVuIG5vdXZlYXUgZG9jdW1lbnQgUiBNYXJrZG93biwgZW4gcGFzc2FudCBvdXRyZSBsZSBmb3JtYXQgYmFzaXF1ZSBxdWUgKlJzdHVkaW8qIHByb3Bvc2UuIAoKW1F1J2VzdCBjZSBxdSd1biBfVGVtcGxhdGVfIGRlIFIgbWFya2Rvd24/XShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL2RldmVsb3Blcl9kb2N1bWVudF90ZW1wbGF0ZXMuaHRtbD92ZXJzaW9uPTEuMC4xMzYmbW9kZT1kZXNrdG9wKQoKQydlc3QgdW4gZW5zZW1ibGUgZGUgZm9ybWF0cyBldCBkZSBwcm9wcmnDqXTDqXMgcHLDqWTDqWZpbmlzIHF1aSB2b3VzIHBlcm1ldHRlbnQgZCdhY2PDqWzDqXJlciBsZSB0cmF2YWlsIHNpIHZvdXMgYXZleiBsJ2hhYml0dWRlIGQnw6ljcmlyZSBkZXMgZG9jdW1lbnRzIHF1aSBvbnQgbGEgbcOqbWUgc3RydWN0dXJlLiBPbiBwZXV0IGVuIGNyw6llciB1biBhdmVjIFIgTWFya2Rvd24sIG1haXMgY2VsYSBuw6ljZXNzaXRlIHVuIHBldSBkZSB0d2Vhay4uLiAKClZvdXMgcG91dmV6IG7DqWFubW9pbnMgdXRpbGlzZXIgZGVzIF9UZW1wbGF0ZV8gZXhpc3RhbnRzLCBlbiBpbnN0YWxsYW50IGxlIHBhY2thZ2UgYHJ0aWNsZXNgIHBhciBleGVtcGxlIHF1aSB2b3VzIHBlcm1ldHRyYSBkJ2F2b2lyIGxlcyBmb3JtYXRzIHByw6lkw6lmaW5pcyBwb3VyIGxlcyBhcnRpY2xlcyBkYW5zIGRpZmbDqXJlbnRzIGpvdXJuYXV4LiBTaSB2b3VzIHBlbnNleiBwdWJsaWVyIGRhbnMgdGVsIG91IHRlbCBqb3VybmFsLCB2b3VzIHBvdXZleiBkw6lmaW5pciB1biBUZW1wbGF0ZSBwb3VyIGNlIGpvdXJuYWwgcydpbCBuJ2V4aXN0ZSBwYXMgZXQgcsOpZGlnZXIgYXZlYywgb3UgbcOqbWUgbGUgcGFydGFnZXIuIEluc3RhbGxleiBsZSBwYWNrYWdlIGBydGljbGVzYCwKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBldmFsPUZBTFNFfQoKICBpbnN0YWxsLnBhY2thZ2VzKCJydGljbGVzIiwgdHlwZT0ic291cmNlIikKCmBgYAoKUHVpcyB2b3VzIHZlcnJleiBsZXMgZXhlbXBsYWlyZXMgcG91ciBsZXMgYXJ0aWNsZXMgZGFucyBsYSBzZWN0aW9uIGBGcm9tIFRlbXBsYXRlYC4gUG91ciBsZSByZXN0ZSwgw6Agdm91cyBkZSBqb3Vlci4gVm91cyBwb3V2ZXogYWpvdXRlciBkJ2F1dHJlcyBUZW1wbGF0ZXMgZW4gZmFpc2FudCB1biB0b3VyIHN1ciBsYSBbZ2FsbGVyaWUgZGUgUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS9nYWxsZXJ5Lmh0bWwpLgoKIyMgTGUgYm9va2Rvd24KClBldXQtb24gZWNyaXJlIHVuIGxpdnJlIGF2ZWMgZHUgcm1hcmtkb3duPyBPdWksIGMnZXN0IHBvc3NpYmxlLiBFdCBwb3VyIHJlbmRyZSBsZSB0b3V0IGJlYXUsIGF2ZWMgZHUgYGJvb2tkb3duYC4gW0pldGV6LXZvdXMgcG91ciByZWdhcmRlcl0oaHR0cHM6Ly9ib29rZG93bi5vcmcvKS4gU2kgdm91cyB2b3VsZXoganVzdGUgYWNxdWVyaXIgbGVzIGJhc2VzIG5lY2Vzc2FpcmVzIHBvdXIgcmVkaWdlciwgb24gY29udGludWUuCgoKCgojIyBMZSBibG9nZG93bgoKCgojIyBMZSB0aWR5dmVyc2UKCgojIyBMZXMgZmlndXJlcyBhdmVjIGBnZ3Bsb3QyYAoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25nZ3Bsb3QyIi8+CjwvYT4KCgoKIyMgTGVzIHRlc3RzIHN0YXRpc3RpcXVlcwoKPGEgbmFtZT0ibGllbnZlcnNsZXNzdGF0cyIvPgo8L2E+CgoKIyMgTGEgY3JlYXRpb24gZGUgcGFja2FnZSBzb3VzICpSc3R1ZGlvKgoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25wYWNrYWdlIi8+CjwvYT4KCgojIyBMZXMgcGV0aXRzIHBsdXMgcG91ciBmaW5pci4uLgoKSmUgbmUgc2F1cmFpcyB0ZXJtaW5lciBzYW5zIGRvbm5lciB1bmUgZG9jdW1lbnRhdGlvbiBwb3VyIGNldXggZXQgY2VsbGVzIHF1aSAKdmV1bGVudCBhcHByb2ZvbmRpciBsZXVyIGNvbm5haXNzYW5jZSBlbiBzdGF0cyBldCBSLgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKW0xhbmNlUm1hcmtdOiBmaWd1cmVzL091dnJpcl9GaWNoaWVyLnBuZyAiTGFuY2VtZW50IGRlIHJtYXJrZG93biIKW1BhcmFtZXRyZV06IGZpZ3VyZXMvUGFyYW1ldHJlLnBuZyAiQ2hvaXggZGVzIHBhcmFtw6h0cmVzIGR1IGZpY2hpZXI6IHRpdHJlLCBhdXRldXIsIGV0Yy4iCltGaWNoaWVyQmFzaXF1ZV06IGZpZ3VyZXMvRmljaGllckJhc2lxdWUucG5nICJMZSBmaWNoaWVyIHN1ciBsZXF1ZWwgdm91cyB2b3VzIGJhc2V6IHBvdXIgY3LDqWVyIHVuIGRvYyBybWFya2Rvd24iCltPdXRwdXRGb3JtYXRdOiBmaWd1cmVzL3JtZF9vdXRwdXRfZm9ybWF0cy5wbmcgIkxlcyBmb3JtYXRzIGRlIHNvcnRpZSBkZSBybWFya2Rvd24iCltSbWRTeW50YXhdOiBmaWd1cmVzL21kU3ludGF4LnBuZwpbQ2h1bmtQYXJhbWV0ZXJzXTogZmlndXJlcy9wYXJhbWV0cmVzX2NodW5rLnBuZwpbUHJvamV0UnN0dWRpb106IGZpZ3VyZXMvcHJvamVjdF9jcmVhdGlvbi5wbmcKW0NodW5rRW5naW5lXTogZmlndXJlcy9DaHVua0VuZ2luZS5wbmcgIkxlcyBkaWZmZXJlbnRzIGxhbmdhZ2VzIGFzc29jaWVzIGF1eCBjaHVua3MiCltDaHVua0luc2VydGlvbl06IGZpZ3VyZXMvQ2h1bmtJbnNlcnRpb24ucG5nIAoKClteMV06IExlIGByZWFkbWUudHh0YCBxdWUgaidhaSBham91dGUgbidlc3QgcGFzIG9ibGlnYXRvaXJlLCBtYWlzIGlsIHNlcmFpdCBpbnRlcmVzc2FudCBkJ2V4cGxpcXVlcgphdXggZ2VucyBsZSBkb3NzaWVyIGV0IGNlIHF1J2lsIHkgYSBsJ2ludGVyaWV1ciwgb3UgbWVtZSB0b24gZnV0dXIgdG9pIHF1aSBuZSBjb21wcmVuZHJhaXQgcGx1cyByaWVuCmRhbnMgcXVlbHF1ZXMgYW5uZWVzIGF1IHRyYXZhaWwgcXVlIHR1IGF2YWlzIGZhaXQuIENlcnRhaW5zIGVuIGZvbnQgdW4gYHJlYWRtZS5odG1sYCAoZWNyaXQgZW4gbWFya2Rvd24pLCBkJ2F1dHJlcyB1biBgcmVhZG1lLnR4dGAuCgpbXjJdOiBMaWJyZSBhIHZvdXMgZCdvcmdhbmlzZXIgdm90cmUgZG9zc2llciBkZSB0cmF2YWlsIGNvbW1lIHZvdXMgdm91bGV6LCBwb3VydnVlIHF1ZQp2b3VzIGdhcmRpZXogdW5lIGNlcnRhaW5lIHJpZ3VldXIgZGFucyBsJ29yZ2FuaXNhdGlvbi4gSmUgcHJlc2VudGUgaWNpIG1vbiB3b3JrZmxvdyBoYWJpdHVlbCAoUGFzCnZyYWltZW50IHB1aXNxdWUgZGFucyBtb24gd29ya2Zsb3cgaGFiaXR1ZWwsIGxlIGRvc3NpZXIgYGRhdGFgIHNlIHRyb3V2ZSBkYW5zIGBpbnB1dGApCgpbXjNdOiBDZXR0ZSBzZWN0aW9uIHByb3ZpZW50IGQndW4gZG9jdW1lbnQgZXhwbGljYXRpZiBzdXIgbGUgTWFya2Rvd24gcXVlIGonYXZhaXMgZWNyaXMKcHJlYWxhYmxlbWVudC4gTGVzIHBlcnNvbm5lcyBxdWkgdHJvdXZlcmFpZW50IHVuZSBxdWVsY29ucXVlIHNpbWlsaXR1ZGUgYXZlYyB1biBkZSBtZXMgYW5jaWVucwpkb2NzLi4uIH5+Tm8gY29tbWVudHN+fi4KW140XTogSmUgbWUgc3VpcyByZW5kdSBjb21wdGUgcXUnaWwgZXN0IGxvbmcgcXVhbmQgamUgbCdhaSBmaW5pLgpbXjZdOiBDJ2VzdCB2cmFpbWVudCBoeXBlciBzaW1wbGUgZGUgbW9kaWZpZXIgbGUgZm9ybWF0IGRlIHNvcnRpZSB3b3JkClteN106IEplIHZvdXMgcHLDqXNlbnRlIGRlcyBleGN1c2VzIHNpIGlsIHkgYSBxdWVscXVlcyBhY2NlbnRzIHF1aSBtYW5xdWVudCBkYW5zIG1vbiB0ZXh0ZSwKZMO7IMOgIGwndXRpbGlzYXRpb24gYWJ1c2l2ZSBkJ3VuIGNsYXZpZXIgYW5nbGFpcy4K